#include "Rect.h"


SRect SRect::Zero=SRect();

SRect::SRect()
{
    Min=SVec2(0,0); 
    Extent=SVec2(0,0);
};

SRect::SRect(SVec2 InMin,SVec2 InExtent)
{
    Min=InMin;
    Extent=InExtent;
}

SRect::SRect(Float MinX, Float MinY, Float MaxX, Float MaxY)
{
    Min=SVec2(MinX,MinY);
    Extent=SVec2(MaxX-MinX,MaxY-MinY);
}

Float SRect::GetMaxX() const
{
    return Min.X+Extent.X;
}

Float SRect::GetMaxY() const
{
    return Min.Y+Extent.Y;
}

TOptional<SRect> SRect::Intersect(const SRect& Other) const
{
    SRect IntersectArea;
    SVec2 IntersectMax;
    IntersectArea.Min.X= CMathBase::Max(Min.X,Other.Min.X);
    IntersectArea.Min.Y= CMathBase::Max(Min.Y,Other.Min.Y);

    IntersectMax.X=CMathBase::Min(Min.X+Extent.X,Other.Min.X+Other.Extent.X);
    IntersectMax.Y=CMathBase::Min(Min.Y+Extent.Y,Other.Min.Y+Other.Extent.Y);

    IntersectArea.Extent=IntersectMax-IntersectArea.Min;
    
    if(IntersectArea.Extent.X >=0 && IntersectArea.Extent.Y >=0 )
    {
        return IntersectArea;
    }
    return TOptional<SRect>();

}

bool SRect::IsPointIn(const SVec2 &InPoint) const
{
    return 
    InPoint.X>=Min.X 
    && InPoint.Y>=Min.Y 
    && InPoint.X<=(Min.X+Extent.X) 
    && InPoint.Y<=(Min.Y+Extent.Y) 
    ;
}

SVec2 SRect::Clamp(const SVec2 &InPoint) const
{
    return SVec2(
        CMathBase::Clamp(InPoint.X,Min.X,Min.X+Extent.X),
        CMathBase::Clamp(InPoint.Y,Min.Y,Min.Y+Extent.Y)
    );
}

SIntPoint SRect::Clamp(const SIntPoint &InPoint) const
{
    return SIntPoint(
        CMathBase::Clamp(InPoint.X,Min.X,Min.X+Extent.X),
        CMathBase::Clamp(InPoint.Y,Min.Y,Min.Y+Extent.Y)
    );
}
